/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package BLForEntities;

import Entities.BasisReis;
import Entities.Continent;
import Entities.Land;
import Entities.Stad;
import Entities.Vervoersmiddel;
import Entities.VervoersmiddelType;
import Interfaces.ZoekenInterface;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

/**
 *
 * @author dwana
 */
public class BLZoeken implements ZoekenInterface {

    private Connectie connectie;
    EntityManager em = null;
    EntityTransaction et = null;

    public BLZoeken() {
        this.beginConnectie();
    }
    //vervoerstype

    @Override
    public List<VervoersmiddelType> vervoersmiddeltypes() {
        return em.createNamedQuery("VervoersmiddelType.getAllVervoersmiddelType").getResultList();
    }

    @Override
    public List<Continent> continenten() {
        return em.createNamedQuery("Continent.getAllContinent").getResultList();
    }

    @Override
    public Continent getContinentById(int id) {
        Query q = em.createNamedQuery("Continent.getContinentById");
        q.setParameter("id", id);
        Continent continent = (Continent) q.getSingleResult();
        return continent;

    }

    @Override
    public List<Land> landen() {
        return em.createNamedQuery("Land.getAllLand").getResultList();
    }

    @Override
    public List<Land> zoekLanden(int continent_id) {

        Query qc = em.createNamedQuery("Continent.getContinentById");
        qc.setParameter("id", continent_id);
        Continent continent = (Continent) qc.getSingleResult();

        Query q = em.createNamedQuery("Land.getAllLandenByContinentId");
        q.setParameter("continent", continent);

        List<Land> landen = (List<Land>) q.getResultList();

        return landen;

    }

    @Override
    public List<Stad> zoekSteden(int stad_id) {

        Query qc = em.createNamedQuery("Land.getLandById");
        qc.setParameter("id", stad_id);
        Land land = (Land) qc.getSingleResult();

        Query q = em.createNamedQuery("Stad.getStedenByLand");
        q.setParameter("land", land);

        List<Stad> steden = (List<Stad>) q.getResultList();

        return steden;

    }

    @Override
    public List<Stad> steden() {
        return em.createNamedQuery("Stad.getAllStad").getResultList();
    }

//    @Override
//    public List<BasisReis> zoekenBasic(VervoersmiddelType vervoersmiddeltype, Land vertrekplaats, Land Bestemming, Date vertrekdatum, Date einddatum, int aantalPersonen) {
//        Query q = em.createNamedQuery("BasisReis.getAllBasisReisBasic");
//        q.setParameter("vervoersmiddeltype", vervoersmiddeltype);
//        q.setParameter("vertrekplaats", vertrekplaats);
//        q.setParameter("Bestemming", Bestemming);
//        q.setParameter("vertrekdatum", vertrekdatum);
//        q.setParameter("einddatum", einddatum);
//        q.setParameter("aantalPersonen", aantalPersonen);
//       
// List<BasisReis> basisreizen = (List<BasisReis>) q.getResultList();
//        return basisreizen;
//    }
    @Override
    public List<BasisReis> zoekenBasic(int vertrekplaats, int bestemming, Date vertrekdatum, Date einddatum, int personen, int type) {

        Query q = em.createNamedQuery("BasisReis.getAllBasisReisBasic");

        if (vertrekplaats == -1) {
            q.setParameter("vertrekplaats", "%");
        } else {
            q.setParameter("vertrekplaats", "%" + vertrekplaats + "%");
        }

        if (bestemming == -1) {
            q.setParameter("bestemming", "%");
        } else {
            q.setParameter("bestemming", "%" + bestemming + "%");
        }

        if (vertrekdatum == null) {
            q.setParameter("vertrekdatum", "%");
        } else {
            Date datum = vertrekdatum;
            Calendar cal = Calendar.getInstance();
            cal.setTime(datum);

            int d2 = cal.get(Calendar.DAY_OF_MONTH);

            if (d2 <= 9) {
                q.setParameter("vertrekdatum", "%" + cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-0" + cal.get(Calendar.DAY_OF_MONTH) + "%");
            } else {
                q.setParameter("vertrekdatum", "%" + cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH) + "%");
            }
        }

        if (einddatum == null) {
            q.setParameter("einddatum", "%");
        } else {
            Date datum = einddatum;
            Calendar cal = Calendar.getInstance();
            cal.setTime(datum);

            int d2 = cal.get(Calendar.DAY_OF_MONTH);

            if (d2 <= 9) {
                q.setParameter("einddatum", "%" + cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-0" + cal.get(Calendar.DAY_OF_MONTH) + "%");
            } else {
                q.setParameter("einddatum", "%" + cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH) + "%");
            }
        }

        //aantal personen =
        List<BasisReis> basisreizen = (List<BasisReis>) q.getResultList();
        basisreizen = zoekenBasicAantalPersonenUitgebreid(basisreizen, personen, type);
        return basisreizen;
    }

    @Override
    public List<BasisReis> zoekenBasic2(int bestemmingId) {
        //  Stad bestemming = em.find(Stad.class, bestemmingId);   

        Query qc = em.createNamedQuery("Stad.getStadById");
        qc.setParameter("id", bestemmingId);
        Stad bestemming = (Stad) qc.getSingleResult();

        Query q = em.createNamedQuery("BasisReis.getAllBasisReisBasicByBestemming");
        q.setParameter("bestemming", bestemming);
        List<BasisReis> basisreizen = (List<BasisReis>) q.getResultList();
        return basisreizen;
    }

    @Override
    public List<BasisReis> zoekenBasicAantalPersonen(int aantalpersonen, int typeid) {
        //  return een reis waarvan het aantal beschikbare plaatsen
        //van de mogelijk heen en terug vervoersmiddelen groter is dan
        // minste beschikbare plaatsen van de 2.
        // mogelijk inbouwen van vervoersmiddelType
        List<BasisReis> mogelijkebasisreizen = new ArrayList<BasisReis>();
        //min value = aantalbeschikbare plaatsen
        int minvalue = 150;
        //get all reizen
        Query q;
        q = em.createNamedQuery("BasisReis.getAllBasisReis");
        List<BasisReis> basisreizen = (List<BasisReis>) q.getResultList();
        List<Integer> AantalplaatsenVanAlleVervoersmiddelenPerReis = new ArrayList<Integer>();
        //Alle VervoersmiddelTypes op halen voor heen en terug gaan per reis
        for (BasisReis b : basisreizen) {
            List<Vervoersmiddel> allemogelijkvervoersmiddelen;
            // all heen reizen ( dus alle vervoersmiddelen met bestemming bestemming
            // en vertrek vertrek

            q = em.createNamedQuery("Vervoersmiddel.getAllVervoersmiddelByVertrekAndBestemming");
            q.setParameter("bestemming", b.getBestemming());
            q.setParameter("vertrek", b.getVertrek());
            allemogelijkvervoersmiddelen = (List<Vervoersmiddel>) q.getResultList();
            //als er geen heen reizen zijn, niet doen
            if (!(allemogelijkvervoersmiddelen.isEmpty())) {
                q.setParameter("bestemming", b.getVertrek());
                q.setParameter("vertrek", b.getBestemming());
                allemogelijkvervoersmiddelen.addAll((List<Vervoersmiddel>) q.getResultList());
                //normaal nog controle op ook terug reizen
                for (Vervoersmiddel v : allemogelijkvervoersmiddelen) {
                    if (v.getVervoersmiddelType().getId() == typeid) {
                        AantalplaatsenVanAlleVervoersmiddelenPerReis.add(v.getAantalBechikbarePlaatsen());
                    }
                }
                //als het miste aantalplaatsen van alle mogelijkevervoersmiddelen onder de
                //gezocht aantalplaatsen ( paramter) is, kan de klant deze boeken
                for (int plaatenVanVervoers : AantalplaatsenVanAlleVervoersmiddelenPerReis) {
                    if (minvalue > plaatenVanVervoers) {
                        minvalue = plaatenVanVervoers;
                    }
                }
                if (minvalue >= aantalpersonen) {
                    mogelijkebasisreizen.add(b);
                }
            }
        }
        // er moete heen en terug reizen zijn

        return mogelijkebasisreizen;
    }

    public List<BasisReis> zoekenBasicAantalPersonenUitgebreid(List<BasisReis> mogelijk, int aantalpersonen, int typeid) {
        List<BasisReis> join = new ArrayList<BasisReis>();
        List<BasisReis> correctAantalPersonen = zoekenBasicAantalPersonen(aantalpersonen, typeid);

        for (BasisReis br : correctAantalPersonen) {

            for (BasisReis b : mogelijk) {
                if (b == br) {
                    join.add(b);
                }
            }

        }

        return join;
    }

    public double getGoedkoopsteHeenEnterugreisVanVertrekidEnBestemmingid(int vertrekId, int bestemmingId) {
        double somTweeGoedkoopste = 0;
        List<Double> vervoersmiddellen = new ArrayList<Double>();
        Query q;
        q = em.createNamedQuery("Vervoersmiddel.getAllVervoersmiddelPrijsByVertrekAndBestemming");
        q.setParameter("bestemming", bestemmingId);
        q.setParameter("vertrek", vertrekId);
        vervoersmiddellen = (List<Double>) q.getResultList();
        Collections.sort(vervoersmiddellen);
        somTweeGoedkoopste = vervoersmiddellen.get(0);

        q.setParameter("bestemming", vertrekId);
        q.setParameter("vertrek", bestemmingId);
        vervoersmiddellen = (List<Double>) q.getResultList();
        Collections.sort(vervoersmiddellen);
        somTweeGoedkoopste += vervoersmiddellen.get(0);
        return somTweeGoedkoopste;
    }

    @Override
    public List<Vervoersmiddel> ReturnTweegoedkoopsteVervoersMiddelen(Stad vertrek, Stad bestemming, VervoersmiddelType vervoersmiddeltype) {
        try {
                 List<Vervoersmiddel> cheapest = new ArrayList<Vervoersmiddel>();
        List<Vervoersmiddel> transitional = new ArrayList<Vervoersmiddel>();
        Query q;
        Query q2;
        q = em.createNamedQuery("Vervoersmiddel.getGoedkoopsteVervoermiddelByVertrekEnBestmming");
        q.setParameter("bestemming", bestemming);
        q.setParameter("vertrek",vertrek );
        q.setParameter("vervoersmiddeltype",vervoersmiddeltype );
        q.setMaxResults(1);
        transitional = q.getResultList();
        cheapest.add(transitional.get(0));
        
        transitional.clear();
        
        q2 = em.createNamedQuery("Vervoersmiddel.getGoedkoopsteVervoermiddelByVertrekEnBestmming");
        q2.setParameter("bestemming",vertrek );
        q2.setParameter("vertrek",bestemming );
        q2.setParameter("vervoersmiddeltype",vervoersmiddeltype );
        q2.setMaxResults(1);
        transitional = q2.getResultList();

            
        
        cheapest.add(transitional.get(0));
        return cheapest;   
        } catch (Exception e) {
            return null;
        }

    }
    
    @Override
    public VervoersmiddelType getVervoersmiddelTypeById(int id){
    
        Query q = em.createNamedQuery("VervoersmiddelType.getVervoersmiddelTypeByID");
        q.setParameter("id", id);
        return (VervoersmiddelType) q.getSingleResult();
    }

    private void beginConnectie() {

        connectie = new Connectie();

        if (em == null) {
            em = connectie.getConnectie();
        }

    }
}
